package net.teamclerks.rpgf.character.stats;

import java.util.HashMap;
import java.util.Map;

import net.teamclerks.rpgf.script.director.Director;

/**
 * StatSheet houses all the stat data associated with:<br/>
 * 1) A Character's base Stats<br/>
 * 2) A Character's combined Stats<br/>
 * 3) A piece of Equipment's Stats
 * @author msmith
 *
 */
public abstract class StatSheet
{
  /// DATAPOINTS ///
  protected Map<Integer, Stat> stats;
  
  /// CONTROL DATA ///
  protected Director director;
  
  /// DENY CONSTRUCTOR ///
  private StatSheet(){}
  
  /// PUBLIC CONSTRUCTOR ///
  public StatSheet(Director director)
  {
    this();
    this.director = director;
    this.stats = new HashMap<Integer, Stat>();
  }

  /// PUBLIC FINAL METHODS ///
  /**
   * Conveniece method for finding the value at a given
   * statSlot.
   */
  public final double getStat(int statSlot)
  {
    if(this.stats.get(statSlot) == null)
    {
      return -1;
    }
    return this.stats.get(statSlot).getValue();
  }
  /**
   * @return the stats
   */
  public final Map<Integer, Stat> getStats()
  {
    return stats;
  }
  /**
   * @param stats the stats to set
   */
  public final void setStats(Map<Integer, Stat> stats)
  {
    this.stats = stats;
  }
  
  /// PUBLIC FINAL METHODS ///
  /**
   * Applies the Equipment's stats to this StatSheet's stats based
   * on the keyset of this CharacterEquipmentStatSheet's stats map.
   * <br/><br/>
   * For instance, if the EquipmentStatSheet has 15 str, 10 stam,
   * 20 charisma, and 10 int while this CharacterEquipmentStatSheet 
   * has 100 str, 100 stam, and 100 int, then removeStats should leave
   * this CharacterEquipmentStatSheet with 115 str, 110 stam, and 110
   * int.<br/><br/>
   * Notice that Charimsa didn't carry over because this stat sheet
   * does not have an entry for it in its map.
   * @param stats
   */
  public final void applyStats(StatSheet stats)
  {
    for(int statSlot: stats.getStats().keySet())
    {
      if(this.stats.keySet().contains(statSlot))
      {
        this.stats.get(statSlot).setValue(this.stats.get(statSlot).getValue() + stats.getStats().get(statSlot).getValue());
      }
      else
      {
        // This statSheet doesn't have this attribute, add it.
        this.stats.put(statSlot, new Stat(director,stats.getStats().get(statSlot)));
      }
    }
  }
  /**
   * Removes the Equipment's stats from this StatSheet's stats based
   * on the keyset of this CharacterEquipmentStatSheet's stats map.
   * <br/><br/>
   * For instance, if the EquipmentStatSheet has 15 str, 10 stam,
   * 20 charisma, and 10 int while this CharacterEquipmentStatSheet 
   * has 100 str, 100 stam, and 100 int, then removeStats should leave
   * this CharacterEquipmentStatSheet with 115 str, 110 stam, and 110
   * int.<br/><br/>
   * Notice that Charimsa didn't carry over because this stat sheet
   * does not have an entry for it in its map.
   * @param stats
   */
  public final void removeStats(StatSheet stats)
  {
    for(int statSlot: stats.getStats().keySet())
    {
      this.stats.get(statSlot).setValue(this.stats.get(statSlot).getValue() - stats.getStats().get(statSlot).getValue());
    }
  }
}
